package cn.zifangsky.array.questions;

import org.junit.Test;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * 双色球选号工具，参考：https://datachart.500.com/dlt/zoushi/jbzs_wuf.shtml
 *
 * <p>输入：五区比（即：每个区选择几个号）</p>
 * <p>输出：所有可能的序列</p>
 *
 * @author zifangsky
 * @date 2022/8/13
 * @since 1.0.0
 */
public class Problem_010_NumberSelection {
    /**
     * 每一组只有7个数（总共从1到35）
     */
    public static int segmentLen = 7;

    /**
     * 测试代码
     */
    @Test
    public void testMethods(){
        Integer[] arr1 = new Integer[]{1,1,1,0,2};
        List<String> result1 = genAll(arr1, 0);
        result1.forEach(System.out::println);
        System.out.println("***************");

        Integer[] arr2 = new Integer[]{1,3,0,0,1};
        List<String> result2 = genAll(arr2, 0);
        result2.forEach(System.out::println);
    }

    /**
     * 生成最终的序列
     * @param arr 五区比情况
     * @param curIdx 当前生成第几组的序列（从0开始）
     * @return 最终的所有可能的序列
     */
    private List<String> genAll(Integer[] arr, int curIdx) {
        if(curIdx >= arr.length) {
            return Collections.emptyList();
        }

        int start = segmentLen *curIdx + 1;
        int end = start + segmentLen - 1;
        int num = arr[curIdx];
        if(num < 0) {
            throw new RuntimeException("每个分段个数不能小于0");
        }
        if(num > segmentLen) {
            throw new RuntimeException("每个分段个数不能超过该分段长度");
        }

        //当前这段的选号情况
        List<String> segmentList = genSegment(start, end, 1, num);

        //当前这段不选号，直接返回后面段的选号情况
        if(segmentList.isEmpty()) {
            return genAll(arr, curIdx+1);
        }else {
            //下段的选号情况
            List<String> nextSegmentList = genAll(arr, curIdx + 1);

            List<String> result = new LinkedList<>();
            for (String segment : segmentList) {
                //后面段都不选号，则直接添加当前这段
                if(nextSegmentList.isEmpty()) {
                    result.add(segment);
                }else {
                    for (String nextSegment : nextSegmentList) {
                        result.add(String.format("%s | %s", segment, nextSegment));
                    }
                }
            }

            return result;
        }
    }

    /**
     * 在一个数组内生成指定位数的序列
     * @param start 序列开始数字
     * @param end 序列结束数字
     * @param seq 当前位数
     * @param num 序列总长度
     */
    private List<String> genSegment(int start, int end, int seq, int num){
        if(num == 0) {
            return Collections.emptyList();
        }

        int curEnd = end - num + seq;
        List<String> result = new LinkedList<>();
        for (int i = start; i <= curEnd; i++) {
            String str = i + "";

            //最后一位
            if(seq == num){
                result.add(str);
            }else {
                //还有下一段
                List<String> nextList = genSegment(i + 1, end, seq + 1, num);
                for (String s : nextList) {
                    result.add(String.format("%s,%s", str, s));
                }
            }
        }
        return result;
    }
}
